/*************************
Diese Software ist ein Beispiel (sample code) und unterliegt der Microsoft Public License. 
Die Verwendung des Codes ist unter den Bedingungen der Microsoft Public License erlaubt.
*************************
This software is sample code and is subject to the Microsoft Public License. 
You may use this code according to the conditions of the Microsoft Public License.
*************************/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;

namespace Egora.Pvp
{
  public class PvpAuthorization
  {
    public static PvpAuthorization Parse(string authorizationString)
    {
      PvpAuthorization auth = new PvpAuthorization();
      auth.AddAuthorizations(authorizationString);
      return auth;
    }

    private List<PvpRole> _roles = new List<PvpRole>();
    private string _ou;
    private string _gvOuId;

    public PvpAuthorization()
    {}

    public PvpAuthorization(NameValueCollection headers)
    {
      if (headers != null)
      {
        _ou = headers.Get(PvpHeaderNames.GetHeaderName(PvpHeader.X_AUTHORIZE_Ou));
        _gvOuId = headers.Get(PvpHeaderNames.GetHeaderName(PvpHeader.X_AUTHORIZE_gvOuId));

        string[] authorizationStrings = headers.GetValues(PvpHeaderNames.GetHeaderName(PvpHeader.X_AUTHORIZE_roles));
        if (authorizationStrings != null && authorizationStrings.Length != 0)
        {
          foreach (string authorizationString in authorizationStrings)
          {
            AddAuthorizations(authorizationString);
          }
        }
      }
    }

    public List<PvpRole> Roles
    {
      get { return _roles; }
      set { _roles = value; }
    }

    public string Ou
    {
      get { return _ou;} 
      set { _ou = value;}
    }

    public string GvOuId
    {
      get { return _gvOuId; } 
      set { _gvOuId = value; }
    }

    public void Merge(string authorizationString)
    {
      Merge(Parse(authorizationString));
    }

    public void Merge(PvpAuthorization authorization)
    {
      foreach (PvpRole role in authorization.Roles)
        Merge(role);
    }

    public void Merge(PvpRole role)
    {
      PvpRole existingRole = GetRole(role.Name);
      if (existingRole == null)
      {
        Roles.Add(role);
      }
      else
      {
        existingRole.Merge(role.Parameters);
      }
    }

    public PvpRole GetRole(string name)
    {
      foreach (PvpRole role in Roles)
      {
        if (role.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
          return role;
      }
      return null;
    }

    public override string ToString()
    {
      StringBuilder sb = new StringBuilder();
      foreach (PvpRole role in Roles)
      {
        string roleString = role.ToString();
        if (!String.IsNullOrEmpty(roleString))
          sb.Append(roleString + ";");
      }

      return sb.ToString();
    }

    public string GetSoapFragment()
    {
      StringBuilder sb = new StringBuilder();
      foreach (PvpRole role in Roles)
        sb.Append(role.GetSoapFragment());

      return sb.ToString();
    }

    private void AddRole(PvpRole role)
    {
      PvpRole existingRole = GetRole(role.Name);
      if (existingRole == null)
        Roles.Add(role);
      else
        existingRole.Merge(role.Parameters);
    }

    private void AddAuthorizations(string authorizationString)
    {
      string[] roleStrings = authorizationString.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
      foreach (string roleString in roleStrings)
        AddRole(PvpRole.Parse(roleString, true));
    }

    public bool HasRole(string roleName)
    {
      PvpRole role = new PvpRole(roleName);
      return HasRole(role);
    }

    public bool HasRole(string roleName, NameValueCollection roleParameters)
    {
      PvpRole role = new PvpRole(roleName);
      role.Merge(roleParameters);
      return HasRole(role);
    }

    public bool HasRole(PvpRole pvpRole)
    {
      PvpRole role = GetRole(pvpRole.Name);
      if (role == null)
        return false;

      foreach (string key in pvpRole.Parameters.AllKeys)
      {
        string[] values = role.Parameters.GetValues(key);
        string[] compareValues = pvpRole.Parameters.GetValues(key);

        if (compareValues == null)
          continue;
        if (values==null)
          return false;
        
        List<string> vals = new List<string>(values);
        foreach (string compareVal in compareValues)
        {
          string cv = compareVal;
          if (!vals.Exists(v => v.Equals(cv,StringComparison.InvariantCultureIgnoreCase)))
            return false;
        }
      }
      
      return true;
    }
  }
}